[初心者向け] GitHub ActionsからECS FargateにCI/CDしてみた

[初心者向け] GitHub ActionsからECS FargateにCI/CDしてみた

GitHub ActionsでCI/CDを簡単に実装できるよ!
Clock Icon2021.12.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは!コンサル部のinomaso(@inomasosan)です。

本記事はGitHub Actions Advent Calendar 2021の20日目の記事です。
投稿が遅くなってしまい申し訳ございません!

GitHub ActionsからECSへ簡単にCI/CDできると聞いたので試してみました。

いくつか参考ブログはあったのですが、ワークフローのテンプレートが古くなっていたりしたので改めてブログにまとめてみました。

前提

以下の環境を構築している必要があります。

  • DockerイメージレジストリにECRを使用
  • ECSでコンテナを起動中

GitHub Actionsワークフローについて

今回はGitHub ActionsのDeploy to Amazon ECSというテンプレートからワークフローを作成します。
テンプレートの大まかな内容は以下の通りです。

  • ECRにログイン
  • Dockerfileからコンテナイメージを作成しECRにプッシュ
  • ECSタスク定義のコンテナイメージを新しいものに置き換え
  • 新しいECSタスク定義をデプロイ

ワークフローを利用するためのセットアップについては、テンプレートにコメントがあるので原文のまま掲載します。

# This workflow will build and push a new container image to Amazon ECR,
# and then will deploy a new task definition to Amazon ECS, when there is a push to the main branch.
#
# To use this workflow, you will need to complete the following set-up steps:
#
# 1. Create an ECR repository to store your images.
#    For example: `aws ecr create-repository --repository-name my-ecr-repo --region us-east-2`.
#    Replace the value of the `ECR_REPOSITORY` environment variable in the workflow below with your repository's name.
#    Replace the value of the `AWS_REGION` environment variable in the workflow below with your repository's region.
#
# 2. Create an ECS task definition, an ECS cluster, and an ECS service.
#    For example, follow the Getting Started guide on the ECS console:
#      https://us-east-2.console.aws.amazon.com/ecs/home?region=us-east-2#/firstRun
#    Replace the value of the `ECS_SERVICE` environment variable in the workflow below with the name you set for the Amazon ECS service.
#    Replace the value of the `ECS_CLUSTER` environment variable in the workflow below with the name you set for the cluster.
#
# 3. Store your ECS task definition as a JSON file in your repository.
#    The format should follow the output of `aws ecs register-task-definition --generate-cli-skeleton`.
#    Replace the value of the `ECS_TASK_DEFINITION` environment variable in the workflow below with the path to the JSON file.
#    Replace the value of the `CONTAINER_NAME` environment variable in the workflow below with the name of the container
#    in the `containerDefinitions` section of the task definition.
#
# 4. Store an IAM user access key in GitHub Actions secrets named `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`.
#    See the documentation for each action used below for the recommended IAM policies for this IAM user,
#    and best practices on handling the access key credentials.

やってみた

IAMユーザの作成

GitHub ActionsからECRとECSへアクセスするために、アクセスキー、シークレットアクセスキーをもつIAMユーザを作成します。

AWSアクセスの種類は、AWSマネジメントコンソールへのアクセスは不要なため、アクセスキー - プログラムによるアクセスのみで作成しましょう。

IAMポリシーは既存のAWS管理ポリシーを使用します。権限を最小化したい場合はカスタマー管理ポリシーを作成願います。

  • ECR用:AmazonEC2ContainerRegistryPowerUser
  • ECS用:AmazonECS_FullAccess

別の記事でIAMポリシーの最小権限例を作成してみました。検証目的で動かすだけであれば上記のAWS管理ポリシーで問題ありません

GitHub Actionsワークフローのテンプレート作成

GitHubでリポジトリを作成しActionsタブからDeploy to Amazon ECSConfigureをクリックします。

以下のようなテンプレートが作成されますのでStart commitからCommit new fileをクリックし、ファイルをコミットします。

GitHub Secrets設定

GitHub Actionsで利用するIAMユーザのアクセスキーIDとシークレットアクセスキーを設定します。 SettingsタブからSecretsを選択し、以下のSecretsを作成します。

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

ワークフロー関連のファイル準備

先ほどワークフロー用のテンプレートを作成したリポジトリをcloneしてきます。

git clone https://github.com/<ユーザ名>/<リポジトリ名>.git

今回の最終的なフォルダ構成は以下の通りとなりますので、必要なファイルを準備していきます。

├── .git
├── .github
│   └── workflows
│       └── aws.yml
├── Dockerfile
├── html
│   └── index.html
└── task-definition.json

GitHub Actionsワークフロー

envの変数の値を、既存のECRとECS等を元に修正します。 以下は修正後の例となります。

env:
  AWS_REGION: ap-northeast-1                   # set this to your preferred AWS region, e.g. us-west-1
  ECR_REPOSITORY: githubactions-httpd          # set this to your Amazon ECR repository name
  ECS_SERVICE: httpd-service               # set this to your Amazon ECS service name
  ECS_CLUSTER: httpd-cluster                # set this to your Amazon ECS cluster name
  ECS_TASK_DEFINITION: task-definition.json # set this to the path to your Amazon ECS task definition
                                               # file, e.g. .aws/task-definition.json
  CONTAINER_NAME: httpd-container           # set this to the name of the container in the
                                               # containerDefinitions section of your task definition

コンテナ関連

今回はApache httpdをベースにどうもinomasoです!!と表示させるコンテナイメージを作成します。

FROM httpd:latest
COPY ./html /usr/local/apache2/htdocs/
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>test</title>
</head>

<body>
    <h1>どうもinomasoです!!</h1>
</body>

</html>

ECSタスク定義

Apache httpd用にシンプルなECSタスク定義を作成していきます。 imageはGitHub Actionsワークフロー実行時に置き換わるため、仮の値で大丈夫です。

{
    "family": "httpd-task",
    "networkMode": "awsvpc",
    "containerDefinitions": [
      {
        "name": "httpd-container",
        "image": "httpd",
        "portMappings": [
          {
            "containerPort": 80,
            "hostPort": 80,
            "protocol": "tcp"
          }
        ],
        "essential": true
      }
    ],
    "runtimePlatform": {
      "cpuArchitecture": "X86_64",
      "operatingSystemFamily": "LINUX"
    },
    "requiresCompatibilities": [
      "FARGATE"
    ],
    "executionRoleArn": "ecsTaskExecutionRole",
    "cpu": "256",
    "memory": "512"
}

ワークフロー実行

変更、作成したファイルを、GitHubリポジトリにプッシュします。

git add .
git commit -m 'initial commit'
git push

GitHub Actionsワークフローによるデプロイが正常に完了すると、以下のような画面が表示されます。

imageもデプロイ中に変更されていることが判ります。

Apache表示確認

正常にどうもinomasoです!!と表示されることを確認できました。

GitHub Actions無料枠

GitHub Actionsはパブリックリポジトリとセルフホストランナーでは無料で利用できますが、プライベートリポジトリでは無料枠+従量課金となります。
無料枠はGitHubアカウントの製品やホストするOSによるため、詳細は以下リンクを参照願います。

参考URL

まとめ

GitHub Actionsを初めて触ってみたので、勘所を掴むまで時間がかかってしまいました。 最近のアップデートでIAMユーザの代わりにIAMロールを使用できるようになったと聞いたので、次回のブログで挑戦したいと思います!

別の記事でIAMロールを活用した記事を作成してみました。AWSクレデンシャルをよりセキュアに扱いたい場合は、こちらの記事もご参照ください!

この記事が、どなたかのお役に立てば幸いです。それでは!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.